package ca.jsbr.as2js_lib.display.canvas.view 
{
	import ca.jsbr.as2js_lib.display.canvas.View;
	import ca.jsbr.as2js_lib.utils.generic.BrowserUtils;
	import ca.jsbr.as2js_lib.utils.geom.Point;
	import ca.jsbr.as2js_lib.utils.geom.Rect;
	import flash.display.Sprite;
	import js.document;
	import js.element.canvas.CanvasGradient;
	import js.element.canvas.CanvasRenderingContext2D;
	import js.element.canvas.ImageData;
	import js.element.HTMLCanvasElement;
	/**
	 * ...
	 * @author jsbr [jsricard@lvlstudio.com]
	 */
	public class ShapeView extends View
	{
		private var _gradient:Array;
		private var _canvas:HTMLCanvasElement;
		private var _ctx:CanvasRenderingContext2D;
		private var _fill:Boolean;
		private var _stroke:Boolean;
		private var _modified:Boolean;
		private var _imgData:ImageData;
		private var _colors:Array;
		private var _positions:Array;
		private var _angle:Number;
		private var _end:Point;
		private var _start:Point;
		private var _fillStyle:String;
		private var _globalAlpha:Number;
		private var _strokeStyle:String;
		private var _lineWidth:Number;
		
		public function ShapeView() 
		{
			_gradient = [];
			_canvas = document.createElement("canvas");
			//document.body.appendChild(_canvas);
			defineSize(10, 10);
			_ctx = _canvas.getContext("2d");
			_modified = true;
		}
		
		private function defineSize(w:Number, h:Number):void
		{
			
			if (w > _width)
			{
				_canvas.width = w;
				_width = w;
			}
			if (h > _height)
			{
				_canvas.height = h;
				_height = h;
			}
		}
		
		public function clear () : void
		{
			_ctx.clearRect(0, 0, width, height);
			/*if (BrowserUtils.getBrowserName() == BrowserUtils.INTERNET_EXPLORER) {
				
				_canvas = document.createElement("canvas");
			}*/
			_imgData = null;
		}
		
		public function lineStyle(size:Number, color:String):void 
		{
			_stroke = true;
			_strokeStyle = color;
			_lineWidth = size;
		}
		
		public function beginFill (color:String, alpha:Number = 1) : void
		{
			_fill = true;
			_fillStyle = color;
			_globalAlpha = alpha;
		}
		
		public function beginGradientFill (colors:Array,positions:Array=null,start:Point=null,end:Point=null):void
		{
			//trace("beginGradientFill");
			_start = start?start:new Point(0,0);
			_end = end?end:new Point(0, 1);
			if(positions)
				_positions = positions;
			else
			{
				_positions = [];
				for ( var i = 0; i < colors.length; i++)
				{
					_positions.push(1/(colors.length - 1)*i);
				}
			}
			_colors = colors;
			_fill = true;
		}
		
		
		public function drawRect (x:Number, y:Number, width:Number, height:Number) : void
		{
			defineSize(x + width, y + height);
			_ctx.rect(x, y, width, height);
			_modified = true;
		}
		
		public function moveTo (x:Number, y:Number) : void
		{
			defineSize(x, y);
			_ctx.beginPath();
			_ctx.moveTo(x, y);
			
			_modified = true;
		}
		
		public function lineTo (x:Number, y:Number) : void
		{
			defineSize(x, y);
			_ctx.lineTo(x, y);
			
			_modified = true;
		}
		
		public function endFill() : void
		{
			if (_fill) {
				if (_colors && _colors.length)
				{
					var gradient:CanvasGradient = _ctx.createLinearGradient(width * _start.x, height * _start.y, width * _end.x, height * _end.y);
					for (var i = 0; i < _colors.length; i++)
					{
						gradient.addColorStop(_positions[i], _colors[i]);
					}
					_ctx.fillStyle = gradient;
				}
				if (_fillStyle)
				{
					_ctx.fillStyle = _fillStyle;
					_ctx.globalAlpha = _globalAlpha;
				}
				_ctx.fill();
			}
			if (_stroke) {
				_ctx.strokeStyle = _strokeStyle;	
				_ctx.lineWidth = _lineWidth;	
				_ctx.stroke();
			}
			
			_ctx.closePath();
		}
		
		public function drawRoundRect (x:Number, y:Number, width:Number, height:Number, ellipseWidth:Number, ellipseHeight:Number = null) : void
		{
			defineSize(x + width, y + height);
			_ctx.moveTo(x + ellipseWidth, y);
			_ctx.lineTo(x + width - ellipseWidth, y);
			_ctx.quadraticCurveTo(x + width, y, x + width, y + ellipseHeight);
			_ctx.lineTo(x + width, y + height - ellipseHeight);
			_ctx.quadraticCurveTo(x + width, y + height, x + width - ellipseWidth, y + height);
			_ctx.lineTo(x + ellipseWidth, y + height);
			_ctx.quadraticCurveTo(x, y + height, x, y + height - ellipseHeight);
			_ctx.lineTo(x, y + ellipseHeight);
			_ctx.quadraticCurveTo(x, y, x + ellipseWidth, y);
			_modified = true;
			
		}
		
		public function drawCircle (x:Number, y:Number, radius:Number) : void
		{
			defineSize(x + radius, y + radius);
			_ctx.arc(x, y, radius, 0, Math.PI * 2, true);
			_modified = true;
			
		}

		public function drawEllipse (x:Number, y:Number, width:Number, height:Number) : void
		{
			defineSize(x + width* 0.5, y + height* 0.5);
			_ctx.arc(x, y, width * 0.5, height * 0.5, Math.PI * 2, true);
			_modified = true;
			
		}
		
		override public function render(ctx:CanvasRenderingContext2D, view:Rect = null):void 
		{
			if (_modified)
				_imgData = _ctx.getImageData(0, 0, width, height);
			if(_imgData)
				ctx.putImageData(_imgData, stageX, stageY);
		}

	}

}